<!doctype html>
<head>
  <style>
    body {
      font-family: 'Helvetica', sans-serif;
    }

    .board-cell {
      border: 1px solid #666;
      box-sizing: border-box;
      display: inline-block;
      font-size: 32px;
      height: 100px;
      line-height: 100px;
      text-align: center;
      width: 100px;
    }

    .board-cell .content {
      display: inline-block;
      vertical-align: middle;
    }
  </style>
</head>
<body>
  <h1>Tic Tac Toe</h1>
  <p>Current player turn: <span class="js-current-player"></span></p>
  <div class="js-board"></div>
  <button class="js-reset">Reset</button>
  <script>
    // We will spend the next 45 minutes building a single-page web app that implements a Tic-Tac-Toe game. jQuery has been included for you. We'll implement the following features in order:

    // 1. Render a 3x3 board. You can hardcode some X and O values within the cell for starters.
    // 2. Implement the add symbol functionality that adds a X or O into a cell whenever the player clicks on it.
    // 3. Rotate between the players whenever a move is made. Update the current player display.
    // 4. Check for end game conditions after each move and display the winner if any.
    // horizontally, vertically, diagonally
    // 5. After a winner has been determined, disable further moves on the board.
    // 6. Add a button to reset the game state.
    (() => {
      function init() {
        const DOM = {
          $currentPlayer: document.querySelector('.js-current-player'),
          $board: document.querySelector('.js-board'),
          $resetButton: document.querySelector('.js-reset'),
        };
        const SIZE = 3;
        function initialState() {
          return {
            boardModel: Array(SIZE).fill(null).map(_ => Array(SIZE).fill(null)),
            players: ['X', 'O'],
            currentPlayer: 0,
            gameEnded: false,
            turn: 0,
          };
        }
        let state = initialState();

        function renderBoard() {
          DOM.$currentPlayer.textContent = state.players[state.currentPlayer];
          // Assuming SIZE > 0.
          DOM.$board.innerHTML = '';
          for (let i = 0; i < SIZE; i++) {
            const $row = document.createElement('div');
            $row.classList.add('board-row');
            for (let j = 0; j < SIZE; j++) {
              const $cell = document.createElement('div');
              $cell.classList.add('board-cell');
              $cell.setAttribute('data-i', i);
              $cell.setAttribute('data-j', j);
              const $content  = document.createElement('span');
              $content.classList.add('content');
              $content.textContent = state.boardModel[i][j];
              $cell.appendChild($content);
              $row.appendChild($cell);
            }
            DOM.$board.appendChild($row);
          }
        }

        function checkWinning(board, player) {
          // Check horizontal.
          for (let i = 0; i < SIZE; i++) {
            if (board[i].every(cell => cell === player)) {
              return true;
            }
          }

          // Check vertical.
          for (let j = 0; j < SIZE; j++) {
            let verticalAllPlayer = true;
            for (let i = 0; i < SIZE; i++) {
              if (board[i][j] !== player) {
                verticalAllPlayer = false;
                break;
              }
            }
            if (verticalAllPlayer) {
              return verticalAllPlayer;
            }
          }

          // Check diagonal South-East.
          let diagonalAllPlayer = true;
          for (let i = 0; i < SIZE; i++) {
            if (board[i][i] !== player) {
              diagonalAllPlayer = false;
              break;
            }
          }
          if (diagonalAllPlayer) {
            return diagonalAllPlayer;
          }

          // Check diagonal North-East.
          diagonalAllPlayer = true;
          for (let i = SIZE - 1, j = 0; i >= 0; i--, j++) {
            if (board[i][j] !== player) {
              diagonalAllPlayer = false;
              break;
            }
          }
          if (diagonalAllPlayer) {
            return diagonalAllPlayer;
          }

          return false;
        }

        function attachEventListeners() {
          DOM.$board.addEventListener('click', (event) => {
            if (state.gameEnded) {
              return;
            }
            if (!event.target.classList.contains('board-cell')) {
              return;
            }
            const $cell = event.target;
            const i = parseInt($cell.getAttribute('data-i'), 10);
            const j = parseInt($cell.getAttribute('data-j'), 10);
            if (state.boardModel[i][j] !== null) {
              alert('Cell has already been taken!');
              return;
            }
            const player = state.players[state.currentPlayer];
            state.boardModel[i][j] = player;
            const winningMove = checkWinning(state.boardModel, player);
            state.turn++;
            if (!winningMove) {
              state.currentPlayer = (state.currentPlayer + 1) % 2;
              renderBoard();
              if (state.turn === SIZE * SIZE) {
                alert('It\'s a draw!');
              }
            } else {
              renderBoard();
              state.gameEnded = true;
              alert(`Player ${player} wins!`);
            }
          });

          DOM.$resetButton.addEventListener('click', () => {
            if (confirm('Start a new game?')) {
              state = initialState();
              renderBoard();
            }
          });
        }

        renderBoard();
        attachEventListeners();
      }

      document.addEventListener('DOMContentLoaded', init);
    })();
  </script>
</body>
</html>
